home *** CD-ROM | disk | FTP | other *** search
/ AI Game Programming Wisdom / AIGameProgrammingWisdom.iso / SourceCode / 10 Scripting / 02 Berger / scc / scc-lexer.l < prev    next >
Encoding:
Lex Description  |  2001-10-16  |  3.7 KB  |  112 lines

  1. %{
  2. // This file contains all the rules that GNU Flex needs to identify tokens in
  3. // the script source code.  GNU Flex is a lexical analyzer (or lexer) that
  4. // finds tokens in the input stream.  Flex is a tool that is commonly used in
  5. // conjunction with GNU Bison and more information about this tool can be
  6. // found at:   http://www.gnu.org/software/flex/
  7.  
  8. #include "SCC.H"
  9. #include "PTNode.H"
  10. #include "scc-parser.h"
  11.  
  12. // NOTE: The C-style comments below are intentional.  Flex does not like
  13. // C++-style comments inside of its rules definitions below.  Also, you want
  14. // to make sure that the comment does not start in the first column.  Flex
  15. // does not have any way to know distinguish between the /* comment and the
  16. // regular expression /*
  17.  
  18.  
  19. // The symbol table is externed in SCC.H, so we need to simply allocate the
  20. // space for it here.
  21. SymbolTable symtbl;
  22.  
  23. // This function will called by the lexer when it encounters an identifier.
  24. // It handles returning the proper data to the parser.
  25. int GetIdentifier();
  26.  
  27. %}
  28.  
  29.  
  30.   /* Define the regular expressions for comments, whitespace, and numbers. */
  31. comment             \/\/.*$
  32. ws                  [\r\n\t ]+
  33. number              [0-9]+
  34. identifier          [_a-zA-Z][_a-zA-Z0-9]*
  35.  
  36.  /* This option tells Flex that this script is never ran interactively.  This
  37.   * is needed for Windows builds since a few UNIX functions are not
  38.   * implemented by Microsoft. */
  39. %option never-interactive
  40.  
  41.  
  42. %%
  43.  
  44.  
  45. {comment}           /* comments are ignored */
  46. {ws}                /* whitespace is ignored */
  47.  
  48. {number}            {
  49.                        /* This rule matches any integer found in the input
  50.                         * stream.  The matched text will be in the yytext
  51.                         * string, and we need to convert it to an integer.
  52.                         * After this is done, create a new constant parse tree
  53.                         * node and return this node to the parser.  This is
  54.                         * done through the Bison-defined variable 'yylval'. */
  55.  
  56.                       int value = strtol( yytext, NULL, 0 );
  57.                       yylval = new ConstantNode( value );
  58.  
  59.                       return NUMBER;
  60.                     }
  61.  
  62. "else"              return K_ELSE;
  63. "for"               return K_FOR;
  64. "if"                return K_IF;
  65.  
  66. {identifier}        return GetIdentifier();
  67.  
  68.  /* This regular expression returns any character that was not matched by a
  69.   * rule above to the parser.  This allows the parser to understand the single
  70.   * letter tokens such as + and - */
  71. .           return yytext[0];
  72.  
  73.  
  74. %%
  75.  
  76.  
  77. // Flex requires that this function is defined.  It will call this function
  78. // whenever it reaches the end of the input stream.  If this function returns
  79. // 1, then Flex will terminate reading.  This function is commonly used to
  80. // switch to another file when the current one is finished (for example, the
  81. // user entered two scripts on the command line).
  82. int yywrap()
  83. {
  84.   return 1;
  85. }
  86.  
  87.  
  88. int
  89. GetIdentifier()
  90. {
  91.   // This function needs to inform the parser that we have encountered an
  92.   // identififer.  For newly encountered variables, a new identifier node to
  93.   // track the variable and it is stuffed into the symbol table.  When the
  94.   // variable is encountered again, the previously allocated identifier node
  95.   // is returned.  This ensures that the parser only sees one pointer per
  96.   // variable.
  97.  
  98.   string name = yytext;
  99.   SymbolTable::iterator i = symtbl.find( name );
  100.  
  101.   if ( i == symtbl.end() ) {
  102.     IdentifierNodePtr identifier = new IdentifierNode( name );
  103.     symtbl.insert( SymbolTable::value_type( name, identifier ) );
  104.  
  105.     yylval = identifier;
  106.   } else {
  107.     yylval = (*i).second;
  108.   }
  109.  
  110.   return IDENTIFIER;
  111. }
  112.